package com.sinodata.bsm.cicp.collector.tomcat;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.Collector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.cicp.util.JmxUtil;
import com.sinodata.bsm.common.vo.ResPropertyValue;

public class ThreadCollector extends Collector {
    private static Logger logger = Logger.getLogger(ThreadCollector.class);
    private final HashMap startedPerMin = new HashMap();

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        String port = this.getParamMap().get("Port");
        String[] propertyNames = new String[] { "ThreadCount", "PeakThreadCount", "DaemonThreadCount", "TotalStartedThreadCount" };
        Object propertyValues[] = null;
        String[] result = new String[5];
        long time = System.currentTimeMillis();
        String key = ip;

        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        String[] propMetas = getPropMeta();
        ResPropertyValue propertyValueX = new ResPropertyValue();
        ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];

        JMXConnector connector = null;
        MBeanServerConnection connection = null;
        try {
            connector = JmxUtil.getConnection(ip, Integer.parseInt(port));
            connection = connector.getMBeanServerConnection();
            ObjectName threadPool = new ObjectName("java.lang:type=Threading");
            Set<ObjectName> set = connection.queryNames(threadPool, null);
            for (ObjectName objectName : set) {
                propertyValues = JmxUtil.getAttribute(connection, objectName, propertyNames);
                for (int i = 0; i < propertyValues.length; i++) {
                    result[i] = propertyValues[i].toString();
                    propValues[i] = ResPropertyValue.createPropValue(propertyValues[i].toString(), propMetas[i]);
                }
            }
        } catch (Exception e) {
            logger.error("when ThreadCollector:" + e);
            throw new CollectorException(e);
        } finally {
            JmxUtil.closeConnector(connector);
        }
        if (startedPerMin.get(key) != null) {
            String tmp = String.valueOf(startedPerMin.get(key));
            String[] valueTime = tmp.split(":");
            result[4] = String.valueOf((Long.parseLong(result[3]) - Long.parseLong(valueTime[0])) * 1000 * 60 / (time - Long.parseLong(valueTime[1])));
            if (Long.parseLong(result[4]) < 0) {
                result[4] = "0";
            }
            propValues[4] = ResPropertyValue.createPropValue(result[4], propMetas[4]);
        } else {
            result[4] = "0";
            propValues[4] = ResPropertyValue.createPropValue(result[4], propMetas[4]);
        }
        startedPerMin.remove(key);
        startedPerMin.put(key, result[3] + ":" + String.valueOf(time));
        propertyValueX.setValues(propValues);
        values.add(propertyValueX);
        return values;
    }

    @Override
    public String[] getParamMeta() {
        //        return new String[] { "名称", "端口" };
        return new String[] { "Name", "Port" };
    }

    @Override
    public String[] getPropMeta() {
        //        return new String[] { "活动线程数量", "活动线程峰值", "守护线程数量", "已启动的线程总数", "每分钟启动线程数量" };
        return new String[] { "$1", "$2", "$3", "$4", "$5" };
    }

}
